home *** CD-ROM | disk | FTP | other *** search
- /*
- * B G _ D O U B L . C
- * This module handles whether doubling and rejection of doubles
- * O.F.Ransen: 7th January 1993
- * This version: 31st December 1993
- *
- */
-
- #include <stdlib.h>
- #include <stdio.h>
- #include <conio.h>
- #include "mousy.h"
- #include "bg.h"
-
- /*************************************************************************/
-
- int Target_Score = 3 ;
- int Double_Value = 1 ;
- Player_t Double_Possessor = NULL_PLAYER ;
- boolean No_Cube = FALSE ;
- int N_Moves = 0 ;
-
- const double Pips_Per_Throw = 8.75 ;
-
- static boolean Can_Double (Player_t Player) ;
- static boolean Selected_Double_Button (short x, short y) ;
-
- /*************************************************************************/
-
- boolean Human_Doubles (Player_t Player)
- /*
- PURPOSE: To wait until the mouse is clicked, inside or outside the
- doubling button. We wait only if doubling is allowed.
- */
- {
- if (Can_Double (Player)) {
-
- short User_Input,x,y ;
- boolean Finished ;
- extern boolean F10_Hit ;
-
- Print_Message (DBL_MSG) ;
- Show_Mouse_Cursor () ;
- Set_Cursor_Shape (QUESTION_SHP,0,0) ;
-
- Finished = FALSE ;
- do {
- User_Input = Get_Mouse_Or_Key (&x,&y) ;
- if (User_Input & (LEFT_BIT | RIGHT_BIT)) {
- Finished = TRUE ;
- } else if (User_Input & FUN_BIT) {
- if ((User_Input & CHAR_MASK) == F10_KEY) {
- Hide_Mouse_Cursor () ;
- F10_Hit = TRUE ;
- return (FALSE) ;
- }
- }
- } while (!Finished) ;
-
- Hide_Mouse_Cursor () ;
-
- return (Selected_Double_Button (x,y)) ;
-
- } else {
- return (FALSE) ;
- }
- }
-
- /*************************************************************************/
-
- static boolean Can_Double (Player_t Player)
- /*
- PURPOSE: To return TRUE if the player is allowed to double.
- */
- {
- if ((Double_Possessor != Player) && (Double_Possessor != NULL_PLAYER)) {
- return (FALSE) ;
- } else if (Double_Value >= 32) {
- /* Cannot go beyond this value */
- return (FALSE) ;
- } else if (No_Cube) {
- return (FALSE) ;
- } else {
- return (TRUE) ;
- }
- }
-
- /*************************************************************************/
-
- static boolean Selected_Double_Button (short x, short y)
- /*
- PURPOSE: To return TRUE if the player doubled by clicking inside
- the doubling box, and if it was legal to do so.
- */
- {
- extern Screen_Const_t Grafs ;
- if ((x >= Grafs.Double_X) && (x <= (Grafs.Double_X + Grafs.Grid_Wide))) {
- if ((y >= Grafs.Double_Y) && (y <= (Grafs.Double_Y + Grafs.Grid_High))) {
- /* Mouse clicked inside double button */
- return (TRUE) ;
- }
- }
- return (FALSE) ;
- }
-
- /*************************************************************************/
-
- boolean Computer_Doubles (Player_t Comp, Layout_t Curr_Lay[2])
- /*
- PURPOSE: To see if the computer wants to double
- */
- {
- short My_Pips,His_Pips ; /* Positive is good for the player */
- short His_Pieces,My_Pieces ;
- double My_Throws,His_Throws ;
- long My_Est,His_Est ;
- Player_t Opp ;
- extern Stats_t Statistics[N_PLAYERS] ;
-
- if (!Can_Double(Comp)) {
- return (FALSE) ;
- }
-
- Opp = OPPONENT (Comp) ;
-
- /*
- * Don't bother doubling if you'd win anyway without it.
- */
- if (Statistics[Comp].Games_Won == (Target_Score-1)) {
- return (FALSE) ;
- }
-
- /*
- * Don't double if only a few pieces left on the board, too
- * complicated and subtle a problem for a poor computer.
- */
- if (Total_Pieces_On_Board (Curr_Lay[Comp],Curr_Lay[Opp]) < 12) {
- return (FALSE) ;
- }
-
- if (!Overlap(Curr_Lay[Comp],Curr_Lay[Opp])) {
- /*
- * There is no overlap, so a basic piece and pip count
- * analysis is sufficient
- */
-
- My_Pips = Pip_Count (Curr_Lay[Comp]) ;
- His_Pips = Pip_Count (Curr_Lay[Opp]) ;
- My_Throws = (My_Pips / Pips_Per_Throw) - 1 ;
- His_Throws = (His_Pips / Pips_Per_Throw) ;
-
- if (My_Throws <= (His_Throws/2.0)) {
- /*
- * May be worth doubling because I have double the chance of
- * reaching home before him.
- */
- My_Pieces = Pieces_On_Board (Curr_Lay[Comp]) ;
- His_Pieces = Pieces_On_Board (Curr_Lay[Opp]) ;
- if (His_Pieces < My_Pieces) {
- return (FALSE) ; /* He has less pieces to take off */
- } else {
- return (TRUE) ;
- }
- } else {
- return (FALSE) ;
- }
- }
-
- /*
- * I am losing, he is within one game of winning, double out
- * of desperation...
- */
- if ((Statistics[Opp].Games_Won == (Target_Score-1)) &&
- (Statistics[Comp].Games_Won < (Target_Score-1))) {
- return (TRUE) ;
- }
-
- /*
- * Look at my view of my changes of winning...
- */
- My_Est = Evaluate_Move (Curr_Lay[Comp],Curr_Lay[Opp],Comp) ;
-
- /*
- * Look at my view of his chances of winning...
- */
- His_Est = Evaluate_Move (Curr_Lay[Opp],Curr_Lay[Comp],Comp) ;
- if (My_Est > (His_Est*2)) {
- return (TRUE) ;
- } else {
- return (FALSE) ;
- }
- }
-
- /*************************************************************************/
-
- boolean Human_Rejects_Double (void)
- /*
- PURPOSE: To return TRUE if the Human rejects the double.
- */
- {
- short User_Input,x,y ;
- boolean Finished ;
- extern boolean F10_Hit ;
-
- Print_Message (ACC_DBL_MSG) ;
- Show_Mouse_Cursor () ;
- Set_Cursor_Shape (QUESTION_SHP,0,0) ;
-
- do {
- User_Input = Get_Mouse_Or_Key (&x,&y) ;
- if (User_Input & (LEFT_BIT | RIGHT_BIT)) {
- Finished = TRUE ;
- } else if (User_Input & FUN_BIT) {
- if ((User_Input & CHAR_MASK) == F10_KEY) {
- F10_Hit = TRUE ;
- return (FALSE) ;
- }
- }
- } while (!Finished) ;
-
- Hide_Mouse_Cursor () ;
-
- if (Selected_Double_Button (x,y)) {
- return (FALSE) ;
- } else {
- return (TRUE) ;
- }
- }
-
- /*************************************************************************/
-
- boolean Computer_Rejects_Double (Player_t Comp, Layout_t Curr_Lay[2])
- /*
- PURPOSE: To see if the computer rejects a double in these circs.
- */
- {
- short My_Pips,His_Pips ; /* Positive is good for the player */
- long My_Est,His_Est ;
- double My_Throws,His_Throws ;
- Player_t Opp ;
- extern Stats_t Statistics[N_PLAYERS] ;
- extern int Target_Score ;
-
- Opp = OPPONENT(Comp) ;
-
- /*
- * Don't refuse if, by refusing, you'd lose the whole match.
- */
- if (Statistics[Opp].Games_Won == (Target_Score-1)) {
- return (FALSE) ; /* Don't refuse */
- }
-
- /*
- * Don't refuse if we are just at the start of the game
- */
- if (N_Moves < 10) {
- return (FALSE) ;
- }
-
- My_Pips = Pip_Count (Curr_Lay[Comp]) ;
- His_Pips = Pip_Count (Curr_Lay[Opp]) ;
- My_Throws = (My_Pips / Pips_Per_Throw) ;
- His_Throws = (His_Pips / Pips_Per_Throw) - 1.0 ;
-
- if (My_Throws < His_Throws) {
- /* I would win on a pure pip-count, so... */
- /*
- * Look at my view of my changes of winning...
- */
- My_Est = Evaluate_Move (Curr_Lay[Comp],Curr_Lay[Opp],Comp) ;
- /*
- * Look at my view of his chances of winning...
- */
- His_Est = Evaluate_Move (Curr_Lay[Opp],Curr_Lay[Comp],Comp) ;
- if (My_Est > His_Est) {
- return (FALSE) ; /* Don't reject, accept */
- } else {
- return (TRUE) ;
- }
- } else {
- if ((My_Pips > 100) && (His_Pips > 100)) {
- return (FALSE) ; /* Early in game, don't reject */
- } else {
- return (TRUE) ;
- }
- }
- }
-
- /*************************************************************************/
-
-